Skip to content

Add Static Location and Live Location Support #3531

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 154 commits into
base: develop
Choose a base branch
from

Conversation

nuno-vieira
Copy link
Member

@nuno-vieira nuno-vieira commented Dec 13, 2024

🔗 Issue Links

Resolves https://linear.app/stream/issue/IOS-578/location-attachment

🎯 Goal

Adds support for static and live location attachments in the Low-Level Client SDK.

The UI has been implemented in the Demo App to demonstrate how to use the new location APIs.

📝 Summary

New APIs:

  • ChatChannelController
    • sendStaticLocation() - Sends a static location message to the channel.
    • startLiveLocationSharing() - Starts a live location-sharing message in the channel.
  • ChatMessageController
    • partialUpdateMessage() - Updates the message partially. (It was missing from the SDK)
    • stopLiveLocationSharing() - Stops sharing the live location attachment if it has one.
  • CurrentChatUserController
    • updateLiveLocation() - Updates the location of all active live location messages for the current user.
    • loadActiveLiveLocationMessages() - Loads all active locations of the current user. Should be called only once.
  • CurrentChatUserControllerDelegate
    • didStartSharingLiveLocation() - Notifies whenever the current user is sharing any live location.
    • didStopSharingLiveLocation() - Notifies whenever the current user stopped/expired all live locations.
    • didChangeActiveLiveLocationMessages() - Notifies whenever the current user's live location messages change.
    • didFailToUpdateLiveLocation() - Called whenever a live location failed to update. Mostly should be used for debugging.
  • Throttler
    • The Throttler was part of the UI SDK somehow, so it was moved to the LLC and made public like the Debouncer.
  • ChatMessage
    • sharedLocation - Returns the location if it has one, either live or static.

🛠 Implementation

The SDK at the moment only handles updating the location attachments. The location tracking should be provided by the App. Something like the LocationProvider in the Demo App should be implemented by the customer.

Creating a location attachment

In order to create a new message with a location attachment, the developer can use the ChannelController.sendStaticLocation() or the ChannelController.startSharingLiveLocation().

Sending location updates (Live Location)

The customer is responsible for sending new location updates to the SDK. This is done through the CurrentChatUserController.updateLiveLocation() method. This method will update all the current user's active location attachments. Internally, it uses a activeLiveLocationMessagesObserver that keeps track of the active location attachments of the current user. These changes are also available to the customer through the CurrentChatUserControllerDelegate to make it easier for the developer to know when it should track location updates and when it can turn them off.

Stopping live location attachment

  • ChatMessageController.stopLiveLocationSharing(): Stops a live location attachment in the given message if it has an active location attachment.

Overall Data Flow

sequenceDiagram
    participant App
    participant LocationProvider
    participant SDK
    participant Backend

    Note over App,Backend: Start New Location Share
    App->>LocationProvider: getCurrentLocation()
    LocationProvider-->>App: Return current location
    App->>SDK: startLiveLocationSharing(location)
    SDK->>Backend: Create location message
    Backend-->>SDK: Confirm creation
    SDK->>App: onStartLiveLocationSharing()
    App->>LocationProvider: startMonitoring()

    Note over App,Backend: Location Updates
    LocationProvider->>LocationProvider: Monitor location changes
    LocationProvider->>SDK: didUpdateLocation(location)
    SDK->>Backend: updateLiveLocation
    Note over SDK: 3s Throttling

    Note over App,Backend: Stop Location Share
    App->>SDK: stopLiveLocationSharing()
    SDK->>Backend: Stop location sharing
    Backend-->>SDK: Confirm stop
    SDK->>App: onStopLiveLocationSharing()
    App->>LocationProvider: stopMonitoring()
Loading

🎨 Showcase

Static Live
static.mp4
live.mp4

🧪 Manual Testing Notes

Note: To simulate live location updates in the Simulator, with the Simulator selected, Go to Features > Location > City Bicycle Ride in the top bar of the Mac.

Precondition: Select the Frankfurt C2 environemnt to test the location feature.

Send a static location message ✅
  1. Open a channel with location sharing enabled
  2. Tap on the Attachments Icon
  3. Tap "Send Current Location"
  4. It should render an image snapshot of a map with a Pin
  5. Tapping the attachment should open the map full screen with the Pin
Send a live location message ✅
  1. Open a channel with location sharing enabled
  2. Tap on the Attachments Icon
  3. Tap "Share Live Location"
  4. Set an end time
  5. It should render an image of the map with the avatar of the user in it and a button saying “Stop Sharing”
    • The map is just a static image (Does not update live)
  6. Tapping the attachment should open the map with the user's avatar, and the user's avatar should move when the location updates.
  7. Tapping the "Stop Sharing" button should stop sharing the live location.
  8. It should update the UI, and a label with “Live location ended” appears.
  9. In the full-screen map view, the avatar should not move anymore.
Receiving a live location message ✅
  1. Share a live location attachment from another user
  2. The receiving user should see the location message with “Live until XXX” date.
  3. Once the location has reached the end, it should update the message with “Live location ended”
  4. The same behaviour should happen if the user is in the full-screen map view.
  5. In the full-screen map view, the avatar should not move anymore.
Active live location is ended when the last update is after expiration ✅
  1. Share a live location attachment with a 1-minute expiration
  2. The user keeps updating the location
  3. When the last update has already passed the expiration, it should update to “Live location ended”
  4. The same should happen in the full-screen map view.
Active live location is ended after the expiration is reached ❌
  1. Share a live location attachment with a 1-minute expiration
  2. The user is still, so no location updates are being sent to the server
  3. When the 1-minute is reached, the UI should update to “Live Location Ended” ❌
  4. The same should happen in the full-screen map view. ❌
  5. The location monitoring should also be stopped ❌
Active live location from another user ends after the expiration is reached ❌
  1. Share a live location attachment with a 1-minute expiration with User A
  2. User B receive the live location in the message list.
  3. User A is still, so no location updates are being sent to the server
  4. When the 1-minute is reached, the UI from User B should update to “Live Location Ended” ❌
  5. The same should happen in the full-screen map view. ❌

☑️ Contributor Checklist

  • I have signed the Stream CLA (required)
  • This change should be manually QAed
  • Changelog is updated with client-facing changes
  • Changelog is updated with new localization keys
  • New code is covered by unit tests
  • Comparison screenshots added for visual changes
  • Affected documentation updated (docusaurus, tutorial, CMS)

Summary by CodeRabbit

  • New Features

    • Introduced comprehensive location sharing support, including static and live location sharing in chat messages.
    • Added the ability to send, update, and stop live location sharing within chat channels.
    • Enhanced message and channel models to display and manage shared locations.
    • New UI components for viewing and controlling shared locations, including live status indicators, map previews, user annotations, and a control banner.
    • Added partial message update functionality for selective content and attachment updates.
    • Added delegate callbacks and controller methods for live location lifecycle events.
    • Added a location provider to manage device location services and permissions.
  • Improvements

    • Updated privacy settings and permissions to support location access and background location updates.
    • Expanded channel capabilities to indicate and control location sharing permissions.
    • Enhanced message actions to disable editing for location messages.
    • Improved UI handling for location attachments and live location sharing controls.
    • Added throttling to live location updates to optimize network usage.
    • Refined snapshot caching and UI updates for location previews.
  • Bug Fixes

    • Improved handling and filtering of live location messages to ensure accurate state and error reporting.
  • Tests

    • Added extensive test coverage for location sharing, partial message updates, database persistence, API interactions, and error handling.
  • Chores

    • Updated documentation, changelogs, configuration files, and test data to reflect new location sharing features and permissions.

@nuno-vieira nuno-vieira added 🌐 SDK: StreamChat (LLC) Tasks related to the StreamChat LLC SDK ✅ Feature An issue or PR related to a feature labels Dec 18, 2024
Copy link
Contributor

@martinmitrevski martinmitrevski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't test a lot, since a had constant crashes (shared details on Slack). Let's figure that out first, then I will do another round.

@nuno-vieira nuno-vieira marked this pull request as ready for review January 3, 2025 17:40
@nuno-vieira nuno-vieira requested a review from a team as a code owner January 3, 2025 17:40
@nuno-vieira nuno-vieira changed the title [WIP] Add Static Location and Live Location Support Add Static Location and Live Location Support Jan 3, 2025
@nuno-vieira nuno-vieira force-pushed the add/location-attachments branch from 5e5a9ab to 70218c2 Compare January 3, 2025 22:01
Copy link

github-actions bot commented Jan 3, 2025

1 Warning
⚠️ Big PR

Generated by 🚫 Danger

@Stream-SDK-Bot
Copy link
Collaborator

Stream-SDK-Bot commented Jan 3, 2025

SDK Size

title develop branch diff status
StreamChat 7.55 MB 7.83 MB +295 KB 🟡
StreamChatUI 4.78 MB 4.83 MB +48 KB 🟢

Copy link
Contributor

@martinmitrevski martinmitrevski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Left few comments, let me know what you think.

Copy link
Contributor

@martinmitrevski martinmitrevski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! ✅

@nuno-vieira nuno-vieira added the 🤞 Ready For QA A PR that is Ready for QA label Jan 9, 2025
@testableapple testableapple added 🧪 QAing 🟢 QAed A PR that was QAed and removed 🤞 Ready For QA A PR that is Ready for QA 🧪 QAing labels Jan 9, 2025
@nuno-vieira nuno-vieira force-pushed the add/location-attachments branch from 502d6b5 to f1a4fac Compare January 9, 2025 22:31
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatChannelController_Mock.swift (1)

58-74: Capture the location argument to aid assertions in tests

createNewMessage already records invocation count (createNewMessageCallCount) but does not persist the arguments passed in.
The newly-added location parameter follows the same pattern and is effectively discarded, limiting the mock’s usefulness for tests that need to verify the value propagated to the SDK.

Add a stored property (or extend an existing tuple) to retain the last location value – mirroring what is already done for updateDraftMessage_text.

+    // Stores the last location passed to `createNewMessage`
+    var createNewMessage_location: NewLocationInfo?
 ...
     override func createNewMessage(
         messageId: MessageId? = nil,
         text: String, pinning: MessagePinning? = nil,
@@
         restrictedVisibility: [UserId] = [],
         location: NewLocationInfo? = nil,
         extraData: [String : RawJSON] = [:],
         completion: ((Result<MessageId, Error>) -> Void)? = nil
     ) {
         createNewMessageCallCount += 1
+        createNewMessage_location = location
     }

This tiny addition keeps mocks transparent and makes writing expectations around static/live-location flows straightforward.
No behavioural change, zero production impact.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 722fa33 and 57c9e1e.

📒 Files selected for processing (9)
  • Sources/StreamChat/Controllers/ChannelController/ChannelController.swift (11 hunks)
  • Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift (9 hunks)
  • Sources/StreamChat/Models/Location/NewLocationInfo.swift (1 hunks)
  • Sources/StreamChat/Workers/ChannelUpdater.swift (2 hunks)
  • StreamChat.xcodeproj/project.pbxproj (41 hunks)
  • TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChatChannelController_Mock.swift (1 hunks)
  • TestTools/StreamChatTestTools/SpyPattern/Spy/DatabaseContainer_Spy.swift (4 hunks)
  • Tests/StreamChatTests/Controllers/MessageController/MessageController_Tests.swift (1 hunks)
  • Tests/StreamChatTests/Workers/MessageUpdater_Tests.swift (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • Sources/StreamChat/Models/Location/NewLocationInfo.swift
🚧 Files skipped from review as they are similar to previous changes (7)
  • Sources/StreamChat/Workers/ChannelUpdater.swift
  • StreamChat.xcodeproj/project.pbxproj
  • Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift
  • Tests/StreamChatTests/Controllers/MessageController/MessageController_Tests.swift
  • Sources/StreamChat/Controllers/ChannelController/ChannelController.swift
  • Tests/StreamChatTests/Workers/MessageUpdater_Tests.swift
  • TestTools/StreamChatTestTools/SpyPattern/Spy/DatabaseContainer_Spy.swift
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Test LLC (Debug)
  • GitHub Check: Build LLC + UI (Xcode 15)
  • GitHub Check: Build Test App and Frameworks
  • GitHub Check: Metrics

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
Tests/StreamChatTests/Workers/CurrentUserUpdater_Tests.swift (1)

804-812: Endpoint assertion looks correct – consider also asserting query parameters.

The test verifies only the path and HTTP method. If the endpoint ever gains mandatory query parameters (e.g. pagination, device-id filter), the test will stay green while the call is broken.
Appending an assertion on endpoint?.queryItems now will guard against such regressions with negligible cost.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57c9e1e and 1474c65.

📒 Files selected for processing (2)
  • TestTools/StreamChatTestTools/TestData/DummyData/SharedLocationPayload.swift (1 hunks)
  • Tests/StreamChatTests/Workers/CurrentUserUpdater_Tests.swift (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • TestTools/StreamChatTestTools/TestData/DummyData/SharedLocationPayload.swift
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Automated Code Review
  • GitHub Check: Test LLC (Debug)
  • GitHub Check: Build Test App and Frameworks
  • GitHub Check: Build LLC + UI (Xcode 15)
  • GitHub Check: Metrics

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8fd717b and 841eac4.

📒 Files selected for processing (11)
  • DemoApp/StreamChat/Components/CustomAttachments/DemoComposerVC.swift (1 hunks)
  • DemoApp/StreamChat/Components/CustomAttachments/LocationAttachment/LocationDetailViewController.swift (2 hunks)
  • Sources/StreamChat/APIClient/Endpoints/Payloads/ChannelListPayload.swift (5 hunks)
  • Sources/StreamChat/Database/DTOs/ChannelConfigDTO.swift (3 hunks)
  • Sources/StreamChat/Database/StreamChatModel.xcdatamodeld/StreamChatModel.xcdatamodel/contents (4 hunks)
  • TestTools/StreamChatTestTools/Fixtures/JSONs/Channel.json (1 hunks)
  • TestTools/StreamChatTestTools/Fixtures/JSONs/ChannelPayload.json (1 hunks)
  • TestTools/StreamChatTestTools/Mocks/Models + Extensions/ChatChannel_Mock.swift (2 hunks)
  • TestTools/StreamChatTestTools/TestData/DummyData/ChannelPayload.swift (1 hunks)
  • Tests/StreamChatTests/APIClient/Endpoints/Payloads/ChannelListPayload_Tests.swift (1 hunks)
  • Tests/StreamChatTests/Database/DTOs/ChannelDTO_Tests.swift (1 hunks)
✅ Files skipped from review due to trivial changes (5)
  • TestTools/StreamChatTestTools/Fixtures/JSONs/ChannelPayload.json
  • Tests/StreamChatTests/APIClient/Endpoints/Payloads/ChannelListPayload_Tests.swift
  • Tests/StreamChatTests/Database/DTOs/ChannelDTO_Tests.swift
  • TestTools/StreamChatTestTools/Fixtures/JSONs/Channel.json
  • Sources/StreamChat/APIClient/Endpoints/Payloads/ChannelListPayload.swift
🚧 Files skipped from review as they are similar to previous changes (3)
  • DemoApp/StreamChat/Components/CustomAttachments/DemoComposerVC.swift
  • Sources/StreamChat/Database/StreamChatModel.xcdatamodeld/StreamChatModel.xcdatamodel/contents
  • DemoApp/StreamChat/Components/CustomAttachments/LocationAttachment/LocationDetailViewController.swift
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Test LLC (Debug)
  • GitHub Check: Build LLC + UI (Xcode 15)
  • GitHub Check: Build Test App and Frameworks
  • GitHub Check: Automated Code Review
  • GitHub Check: Metrics
🔇 Additional comments (3)
TestTools/StreamChatTestTools/Mocks/Models + Extensions/ChatChannel_Mock.swift (1)

22-23: LGTM! Mock configuration properly updated for location sharing support.

The new sharedLocationsEnabled parameter is correctly added with appropriate defaults and properly passed to the initializer, maintaining consistency with the existing mock pattern.

Also applies to: 42-43

Sources/StreamChat/Database/DTOs/ChannelConfigDTO.swift (2)

28-28: Property declaration follows Core Data conventions.

The sharedLocationsEnabled property is correctly declared as @NSManaged following the same pattern as other Boolean properties in the DTO.


46-46: Conversion methods properly updated.

The sharedLocationsEnabled property is correctly included in both asModel() and asDTO() conversion methods, ensuring proper bidirectional data flow between the domain model and Core Data representation.

Also applies to: 88-88

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8dbe9af and b1fbd61.

📒 Files selected for processing (18)
  • Sources/StreamChat/APIClient/Endpoints/Payloads/ChannelListPayload.swift (8 hunks)
  • Sources/StreamChat/APIClient/Endpoints/Payloads/IdentifiableModel.swift (1 hunks)
  • Sources/StreamChat/Database/DTOs/ChannelDTO.swift (4 hunks)
  • Sources/StreamChat/Database/DTOs/MessageDTO.swift (11 hunks)
  • Sources/StreamChat/Database/DTOs/SharedLocationDTO.swift (1 hunks)
  • Sources/StreamChat/Database/DatabaseSession.swift (4 hunks)
  • Sources/StreamChat/Database/StreamChatModel.xcdatamodeld/StreamChatModel.xcdatamodel/contents (5 hunks)
  • Sources/StreamChat/Models/Channel.swift (7 hunks)
  • StreamChat.xcodeproj/project.pbxproj (41 hunks)
  • TestTools/StreamChatTestTools/Fixtures/JSONs/Channel.json (2 hunks)
  • TestTools/StreamChatTestTools/Mocks/Models + Extensions/ChatChannel_Mock.swift (8 hunks)
  • TestTools/StreamChatTestTools/Mocks/StreamChat/Database/DatabaseSession_Mock.swift (4 hunks)
  • TestTools/StreamChatTestTools/TestData/DummyData/ChannelPayload.swift (2 hunks)
  • TestTools/StreamChatTestTools/TestData/DummyData/XCTestCase+Dummy.swift (2 hunks)
  • Tests/StreamChatTests/APIClient/Endpoints/Payloads/ChannelListPayload_Tests.swift (3 hunks)
  • Tests/StreamChatTests/APIClient/Endpoints/Payloads/IdentifiablePayload_Tests.swift (1 hunks)
  • Tests/StreamChatTests/Database/DTOs/ChannelDTO_Tests.swift (9 hunks)
  • Tests/StreamChatTests/WebSocketClient/EventMiddlewares/ChannelReadUpdaterMiddleware_Tests.swift (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • Tests/StreamChatTests/WebSocketClient/EventMiddlewares/ChannelReadUpdaterMiddleware_Tests.swift
  • TestTools/StreamChatTestTools/TestData/DummyData/XCTestCase+Dummy.swift
🚧 Files skipped from review as they are similar to previous changes (12)
  • Tests/StreamChatTests/APIClient/Endpoints/Payloads/ChannelListPayload_Tests.swift
  • Sources/StreamChat/APIClient/Endpoints/Payloads/IdentifiableModel.swift
  • Sources/StreamChat/Models/Channel.swift
  • StreamChat.xcodeproj/project.pbxproj
  • TestTools/StreamChatTestTools/Mocks/Models + Extensions/ChatChannel_Mock.swift
  • Sources/StreamChat/APIClient/Endpoints/Payloads/ChannelListPayload.swift
  • TestTools/StreamChatTestTools/Mocks/StreamChat/Database/DatabaseSession_Mock.swift
  • Tests/StreamChatTests/Database/DTOs/ChannelDTO_Tests.swift
  • TestTools/StreamChatTestTools/TestData/DummyData/ChannelPayload.swift
  • Sources/StreamChat/Database/DatabaseSession.swift
  • Sources/StreamChat/Database/DTOs/MessageDTO.swift
  • Sources/StreamChat/Database/StreamChatModel.xcdatamodeld/StreamChatModel.xcdatamodel/contents
🧰 Additional context used
🪛 Biome (1.9.4)
TestTools/StreamChatTestTools/Fixtures/JSONs/Channel.json

[error] 1595-1597: expected , but instead found "active_live_locations"

Remove "active_live_locations"

(parse)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Test LLC (Debug)
  • GitHub Check: Build Test App and Frameworks
  • GitHub Check: Build LLC + UI (Xcode 15)
  • GitHub Check: Metrics
🔇 Additional comments (10)
Tests/StreamChatTests/APIClient/Endpoints/Payloads/IdentifiablePayload_Tests.swift (1)

407-408: LGTM! Test data updated to reflect new payload structure.

The addition of activeLiveLocations: [] to the ChannelPayload initialization correctly updates the test data to align with the new location sharing features. This ensures test compatibility with the enhanced payload structure.

TestTools/StreamChatTestTools/Fixtures/JSONs/Channel.json (1)

1323-1323: LGTM! Well-structured location sharing test data.

The addition of shared_locations config flag and active_live_locations array provides comprehensive test data for the new location sharing features. The location data structure includes all necessary fields that align with the DTO implementation.

Also applies to: 1595-1607

Sources/StreamChat/Database/DTOs/ChannelDTO.swift (3)

77-77: LGTM! Correct Core Data relationship declaration.

The activeLiveLocations property follows the established pattern for Core Data to-many relationships in this codebase.


362-364: LGTM! Correct persistence implementation.

The active live locations are properly saved from the payload using the established pattern of mapping each payload item to a DTO and collecting them into a Set.


603-603: LGTM! Proper model conversion and initialization.

The active live locations are correctly converted from DTOs to model objects and passed to the ChatChannel initializer, maintaining consistency between the persistence and model layers.

Also applies to: 637-638

Sources/StreamChat/Database/DTOs/SharedLocationDTO.swift (5)

8-16: LGTM! Well-structured Core Data entity.

The SharedLocationDTO class properly declares all necessary properties with appropriate types for location data persistence. The relationship to MessageDTO is correctly established.


18-30: LGTM! Proper change propagation implementation.

The willSave() override correctly ensures that location data changes are propagated to the associated message, triggering necessary UI updates. The guards and dirty-marking technique follow established patterns in this codebase.


32-62: LGTM! Consistent static method implementation.

The static methods for loading and creating SharedLocationDTO instances follow the established patterns used throughout the codebase, including proper caching support and fetch request configuration.


65-78: LGTM! Correct model conversion implementation.

The asModel() method properly validates the DTO state and converts all properties to the SharedLocation model, following the established conversion patterns in the codebase.


80-97: LGTM! Proper context extension for persistence.

The saveLocation method follows the established pattern for saving payload data to DTOs, properly handling creation/updates and mapping all properties correctly.

@nuno-vieira nuno-vieira force-pushed the add/location-attachments branch from 440ab55 to 2bd4923 Compare June 20, 2025 14:51
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
77.5% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✅ Feature An issue or PR related to a feature 🧪 QAing 🌐 SDK: StreamChat (LLC) Tasks related to the StreamChat LLC SDK
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants